package com.xianyu.ssoserver.service;

import com.menghao.sso.server.exception.ValidateFailException;
import com.menghao.sso.server.model.Service;
import com.menghao.sso.server.model.credentials.Credentials;
import com.menghao.sso.server.model.credentials.UsernamePasswordCredentials;
import com.menghao.sso.server.model.ticket.ServiceTicket;
import com.menghao.sso.server.model.ticket.TicketGrantingTicket;
import com.menghao.sso.server.registry.TicketRegistry;
import com.menghao.sso.server.repository.UCredentialsRepository;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * <p>认证Service实现.<br>
 *
 * @author menghao.
 * @version 2017/11/17.
 */
@org.springframework.stereotype.Service
public class AuthenticationServiceImpl implements AuthenticationService {

    private final Log log = LogFactory.getLog(this.getClass());

    @Autowired
    private UCredentialsRepository uCredentialsRepository;
    @Autowired
    private TicketRegistry ticketRegistry;

    @Override
    public void validateCredentials(Credentials credentials) throws ValidateFailException {
        if (credentials instanceof UsernamePasswordCredentials) {
            UsernamePasswordCredentials usernamePasswordCredentials =
                    uCredentialsRepository.queryByProperty((UsernamePasswordCredentials) credentials);
            // 验证通过
            if (usernamePasswordCredentials == null) {
                throw new ValidateFailException("用户名与密码不匹配");
            }
        } else {
            throw new ValidateFailException("暂不支持的认证方式");
        }
    }

    @Override
    public void validateGrantingTicket(String ticketGrantingTicketId) throws ValidateFailException {
        if (ticketGrantingTicketId == null) {
            throw new ValidateFailException("未检测到票据信息，请登录");
        }
        final TicketGrantingTicket ticketGrantingTicket = (TicketGrantingTicket) this.ticketRegistry.getTicket(ticketGrantingTicketId);
        if (ticketGrantingTicket == null) {
            log.debug("TicketGrantingTicket [" + ticketGrantingTicket + "] does not exist.");
            throw new ValidateFailException("票据信息校验未通过，请登录");
        }

        if (ticketGrantingTicket.isExpired()) {
            log.debug("ServiceTicket [" + ticketGrantingTicket + "] has expired.");
            this.ticketRegistry.deleteTicket(ticketGrantingTicketId);
            throw new ValidateFailException("身份验证已过期，请重新登录");
        }
        ticketGrantingTicket.updateLastTimeUsed();
    }

    @Override
    public void validateServiceTicket(String serviceTicketId, Service service) throws ValidateFailException {
        if (serviceTicketId == null || service == null) {
            throw new ValidateFailException("未检测到票据信息，请登录");
        }
        final ServiceTicket serviceTicket = (ServiceTicket) this.ticketRegistry.getTicket(serviceTicketId);
        if (serviceTicket == null) {
            log.debug("ServiceTicket [" + serviceTicketId + "] does not exist.");
            throw new ValidateFailException("票据信息校验未通过，请登录");
        }

        if (serviceTicket.isExpired()) {
            log.debug("ServiceTicket [" + serviceTicketId + "] has expired.");
            this.ticketRegistry.deleteTicket(serviceTicketId);
            throw new ValidateFailException("身份验证已过期，请重新登录");
        }
        serviceTicket.incrementCountOfUses();
        serviceTicket.updateLastTimeUsed();

        if (serviceTicket.isExpired()) {
            log.debug("ServiceTicket [" + serviceTicketId + "] has expired.");
            this.ticketRegistry.deleteTicket(serviceTicketId);
            throw new ValidateFailException("身份验证已过期，请重新登录");
        }

        if (!service.equals(serviceTicket.getService())) {
            log.debug("ServiceTicket [" + serviceTicketId + "] does not match supplied service.");
            throw new ValidateFailException("票据信息与服务不匹配，请登录");
        }

    }

}
